package cardmodel

import (
	"context"
	"errors"
	"group-card/common/constant"
	"group-card/common/tool"
	"group-card/model/entity"
	"xorm.io/xorm"
)

var _ CardPublishModel = (*customCardPublishModel)(nil)

type (
	// CardPublishModel is an interface to be customized, add more methods here,
	// and implement the added methods in customCardPublishModel.
	CardPublishModel interface {
		cardPublishModel
		IsExist(query interface{}, args interface{}) (bool, error)                                         // 判断是否存在
		List(ctx context.Context, req *entity.CardPublishReq) ([]*entity.CardPublishResp, int64, error)    // 分页查询
		CreateCardNumber(ctx context.Context, req *entity.CardPublishReq) (*entity.CardPublishResp, error) // 自动生成卡号
		GetCardPublishJoin(ctx context.Context, req *entity.CardPublishReq) (*ConfirmPublishResp, error)   // 获取卡片发行记录详情
		GetCardPublish(ctx context.Context, req *entity.CardPublishReq) (*entity.CardPublishResp, error)   // 获取卡片发行记录详情
		UpdateCardPublishDb(ctx context.Context, db *xorm.Session, req *entity.CardPublishReq) error       // 修改卡片发行记录(事务)
	}

	customCardPublishModel struct {
		*defaultCardPublishModel
	}
)

// NewCardPublishModel returns a model for the database table.
func NewCardPublishModel(conn *xorm.Engine) CardPublishModel {
	return &customCardPublishModel{
		defaultCardPublishModel: newCardPublishModel(conn),
	}
}

//region TODO: 判断是否存在 Author:LiuYanLin Date:2023/04/13 周四 14:52

func (m *defaultCardPublishModel) IsExist(query interface{}, args interface{}) (bool, error) {
	data := new(entity.CardPublishReq)
	has, err := m.conn.Table(m.table).Where(query, args).Exist(data)
	if err != nil {
		tool.GLogLine("判断卡片发行是否存在错误 defaultCardPublishModel IsExist:", err)
		return false, err
	}
	return has, nil
}

//endregion

func (m *defaultCardPublishModel) List(ctx context.Context, req *entity.CardPublishReq) ([]*entity.CardPublishResp, int64, error) {
	sql := m.conn.Table(m.table)

	if req.Columns != "" {
		sql.Select(req.Columns)
	}

	list := make([]*entity.CardPublishResp, 0)
	count, err := sql.Limit(int(req.PageSize), int((req.PageNum-1)*req.PageSize)).FindAndCount(&list)
	if err != nil {
		tool.GLogLine("获取卡面列表失败 defaultCardSkinModel List:", err)
		return nil, 0, err
	}

	return list, count, err
}

func (m *defaultCardPublishModel) CreateCardNumber(ctx context.Context, req *entity.CardPublishReq) (*entity.CardPublishResp, error) {

	columns := "max(end_number) as end_number"

	endNumber := new(entity.CardPublishResp)
	_, err := m.conn.Table(m.table).Select(columns).Get(endNumber)
	if err != nil {
		tool.GLogLine("自动生成卡号失败 defaultCardSkinModel CreateCardNumber:", err)
		return nil, err
	}

	data := new(entity.CardPublishResp)
	if endNumber.EndNumber == 0 {
		data.BeginNumber = constant.InitialBeginNumber + 1
		data.EndNumber = constant.InitialBeginNumber + req.Count
	} else {
		data.BeginNumber = endNumber.EndNumber + 1
		data.EndNumber = endNumber.EndNumber + req.Count
	}

	return data, nil
}

// region TODO:获取卡片发行记录详情  Author:LiuYanLin Date:2023/07/03 周一 11:58
func (m *defaultCardPublishModel) GetCardPublishJoin(ctx context.Context, req *entity.CardPublishReq) (*ConfirmPublishResp, error) {
	columns := "card_publish.customer_id,card_publish.begin_number,card_publish.end_number" +
		",card_publish.service_number,card_publish.status,card_skin.face_value"
	resp := new(ConfirmPublishResp)
	has, err := m.conn.Table(m.table).Select(columns).
		Join("LEFT", "card_skin", "card_publish.skin_id = card_skin.id").
		Where("card_publish.id = ?", req.Id).
		Get(resp)
	if err != nil {
		tool.GLogLine("获取卡片发行记录详情 defaultCardPublishModel GetConfirmPublishJoin:", err)
		return nil, err
	}

	if !has {
		return nil, errors.New("未获取到卡片发行记录")
	}

	return resp, nil
}

//endregion

// region TODO:获取卡片发行记录详情  Author:LiuYanLin Date:2023/07/03 周一 11:58
func (m *defaultCardPublishModel) GetCardPublish(ctx context.Context, req *entity.CardPublishReq) (*entity.CardPublishResp, error) {
	resp := new(entity.CardPublishResp)
	has, err := m.conn.Table(m.table).Select(req.Columns).Where("id = ?", req.Id).Get(resp)
	if err != nil {
		tool.GLogLine("获取卡片发行记录详情 defaultCardPublishModel GetCardPublish:", err)
		return nil, err
	}

	if !has {
		return nil, errors.New("未获取到卡片发行记录")
	}

	return resp, nil
}

//endregion

// region TODO: 修改卡片发行记录(事务) Author:LiuYanLin Date:2023/07/03 周一 13:44
func (m *defaultCardPublishModel) UpdateCardPublishDb(ctx context.Context, db *xorm.Session, req *entity.CardPublishReq) error {
	has, err := db.Table(m.table).Cols(req.Columns).Where("id = ?", req.Id).Update(req)
	if has < 1 || err != nil {
		tool.GLogLine("编辑卡片发行失败(事务) defaultCardPublishModel UpdateCardPublishDb:", err)
		return err
	}
	return nil
}

//endregion
